/*
 * rank_mgr.cpp
 *
 *  Created on: Nov 25, 2013
 *      Author: killerg
 */

#include "../server_deps.h"
#include "../server.h"
#include "../server_cfg.h"

#include "share/util.h"
#include "share/json/json.h"
#include "share/db_mgr.h"
#include "share/cs_msg.pb.h"
#include "share/clock.h"
#include "rank_mgr.h"
#include "player_mgr.h"
#include "game_cfg.h"

void rank_mgr::post_load() {
	{
		stringstream ss;
		ss << "/_design/rank/_view/rank_player";
		ss << "?stale=update_after";
	//    ss << "&full_set=true";
		ss << "&reduce=false";
		ss << "&descending=true";
		ss << "&startkey=[" << (g_cfg->ServerId + 1)<< "%2C" << "null" << "]";
		ss << "&endkey=[" << g_cfg->ServerId << "%2C" << 0 << "]";
		ss << "&connection_timeout=60000";
		ss << "&limit=200";

		bool ret = g_dbs->view(
				ss.str().c_str(),
				[this](db_error_t err, const Json::Value &value){
					const Json::Value &rows = value["rows"];
					player_list.clear();
					player_rank.clear();
					int index = 0;
					for (auto itr = rows.begin(); itr != rows.end(); ++itr, ++index) {
						rank_player_t rank_item;
						const Json::Value &key_json = (*itr).get("key", Json::nullValue);
						rank_item.player_combat_force = key_json.get(1, Json::nullValue).asInt();
						rank_item.playerid = (*itr).get("value", -1).asInt64();

						player_list.emplace_back(rank_item);
						player_rank[rank_item.playerid] = index;
					}
				});
		if (!ret) {
			UTIL_LOG(E, "rank_mgr::post_load rank_player");
		}
	}
	{
		stringstream ss;
		ss << "/_design/rank/_view/rank_player_low";
		ss << "?stale=update_after";
	//    ss << "&full_set=true";
		ss << "&reduce=false";
		ss << "&descending=true";
		ss << "&startkey=[" << (g_cfg->ServerId + 1)<< "%2C" << "null" << "]";
		ss << "&endkey=[" << g_cfg->ServerId << "%2C" << 0 << "]";
		ss << "&connection_timeout=60000";
		ss << "&limit=200";

		bool ret = g_dbs->view(
				ss.str().c_str(),
				[this](db_error_t err, const Json::Value &value){
					const Json::Value &rows = value["rows"];
					player_low_list.clear();
					player_low_rank.clear();
					int index = 0;
					for (auto itr = rows.begin(); itr != rows.end(); ++itr, ++index) {
						rank_player_t rank_item;
						const Json::Value &key_json = (*itr).get("key", Json::nullValue);
						rank_item.player_combat_force = key_json.get(1, Json::nullValue).asInt();
						rank_item.playerid = (*itr).get("value", -1).asInt64();

						player_low_list.emplace_back(rank_item);
						player_low_rank[rank_item.playerid] = index;
					}
				});
		if (!ret) {
			UTIL_LOG(E, "rank_mgr::post_load rank_player_low");
		}
	}


    {
		stringstream ss;
		ss << "/_design/rank/_view/rank_pet";
		ss << "?stale=update_after";
	//    ss << "&full_set=true";
		ss << "&reduce=false";
		ss << "&descending=true";
		ss << "&startkey=[" << (g_cfg->ServerId + 1)<< "%2C" << "null" << "]";
		ss << "&endkey=[" << g_cfg->ServerId << "%2C" << 0 << "]";
		ss << "&connection_timeout=60000";
		ss << "&limit=200";
		bool ret = g_dbs->view(
				ss.str().c_str(),
				[this](db_error_t err, const Json::Value &value){
					const Json::Value &rows = value["rows"];
					pet_list.clear();
					pet_rank.clear();
					int index = 0;
					for (auto itr = rows.begin(); itr != rows.end(); ++itr, ++index) {
						rank_pet_t rank_item;
						const Json::Value &value = (*itr)["value"];

						const Json::Value &key_json = (*itr).get("key", Json::nullValue);
						rank_item.pet_combat_force = key_json.get(1, Json::nullValue).asInt();
						rank_item.serial = value["serial"].asInt64();
						rank_item.pet_name = value["name"].asCString();
						rank_item.protoid = value["proto"].asInt();
						rank_item.owner_id = value["player_id"].asInt64();

						pet_list.emplace_back(rank_item);

						if (pet_rank.count(rank_item.owner_id) == 0) {
							pet_rank[rank_item.owner_id] = index;
						} else if (index < pet_rank[rank_item.owner_id]) {
							pet_rank[rank_item.owner_id] = index;
						}
					}
				});
		if (!ret) {
			UTIL_LOG(E, "rank_mgr::post_load rank_pet");
		}
    }
}

bool rank_mgr::init() {
    post_load();
    g_dbs->wait();

    return true;
}

void rank_mgr::destroy() {
    player_list.clear();
    player_low_list.clear();
    pet_list.clear();
}

void rank_mgr::update() {
	rank_timer -= g_clock->delta;
	if (rank_timer < 0) {
		rank_timer = g_game_cfg->RankIntervalSec;

		post_load();
	}
}

